perm filename NFREG.SAI[PIC,HE] blob sn#430343 filedate 1979-04-04 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	entry reginit,fregion,regterm,regclean
C00011 ENDMK
C⊗;
entry reginit,fregion,regterm,regclean;
begin "NFREG"
REQUIRE "36A" COMPILER!SWITCHES;
require "bufdec.sai" source!file;
external BOOLEAN PROCEDURE BORDER(INTEGER II,JJ,IBUF,OBUF; REFERENCE INTEGER imina,imaxa,jmina,jmaxa; integer value);
own integer reg,curreg,regbuf;
source!l(dynary);
require "⊂⊃<>" delimiters;
dynary(<SAFE integer>,<imina,imaxa,jmina,jmaxa,size>,1);




simple internal integer procedure reginit(integer maskbuf,sizarr);
    begin "reginit"
    integer i,j,iptr,rptr,state,fillnum,rowmax,colmax,ii,jj,totarr;
    if sizarr≤0 then sizarr←6;
    totarr←2↑sizarr;
    reg←0;

    makary(<(1,totarr)>,1,imina);
    makary(<(1,totarr)>,1,imaxa);
    makary(<(1,totarr)>,1,jmina);
    makary(<(1,totarr)>,1,jmaxa);
    makary(<(1,totarr)>,1,size);
    arrclr(size);
    totarr←totarr-1;

    getbuf(rowmax←rows(maskbuf),colmax←colms(maskbuf),sizarr,regbuf←fndbuf);
    putsub(isubst(maskbuf),jsubst(maskbuf),regbuf);


    for i←1 thru rowmax do
	begin "iloop"
	state←0;
	iptr←inptr(i,1,maskbuf);
	for j←1 thru colmax do
	    case state of
		begin "JCASE"
		if ildb(iptr)						! normal start state;
		    then begin "FOUND1"
			if (fillnum←getpnt(i,j,regbuf))=0
			    then begin
				if ¬border(i,j,maskbuf,regbuf,imina[reg←reg+1]←i,
				    imaxa[reg]←i,jmina[reg]←j,jmaxa[reg]←j,fillnum←reg)
				    then begin
					for ii←imina[reg] thru imaxa[reg] do
					    begin
					    dum←outptr(ii,jmina[reg],regbuf);
					    for jj←jmina[reg] thru jmaxa[reg] do
						if ildb(dum)=reg then dpb(0,dum);
					    end;
					jj←j;
					while (jj←jj-1)>0 do
					    if (fillnum←getpnt(i,jj,regbuf))
						then begin
						    state←2;
						    ifcr false thenc PRINT(">>"); endc
						    j←jj;
						    rptr←outptr(i,j+1,regbuf);
						    IPTR←INPTR(I,J+1,MASKBUF);
						    done;
						    end;
					reg←reg-1;
					continue;
					end;
				ifcr true thenc PRINT("#"); endc
				if (imaxa[fillnum]-imina[fillnum]<2)∧(jmaxa[fillnum]-jmina[fillnum]<2)
				    then begin
					border(i,j,maskbuf,regbuf,imina[reg]←i,
					    imaxa[reg]←i,jmina[reg]←j,jmaxa[reg]←j,0);
					state←3;
					reg←reg-1;
					ifcr true thenc PRINT("*"); endc
					end
				    else begin
					add1(size[fillnum]);
					state←1;
					rptr←outptr(i,j+1,regbuf);
					if reg=totarr then begin reg←totarr-1; PRINT("-"); end;
					end;
				end
			    else begin
				add1(size[fillnum]);
				state←1;
				rptr←outptr(i,j+1,regbuf);
				ifcr false thenc PRINT(">"); endc
				end;
			end;
		if ildb(rptr)=0						! checking for inside or outside of region;
		    then if ILDB(IPTR)
			then begin
			    state←2;
			    ifcr false thenc PRINT(">"); endc
			    dpb(fillnum,rptr);
			    add1(size[fillnum]);
			    end
			else begin
			    state←0;
			    ifcr false thenc PRINT("<"); endc
			    end
		    else BEGIN IBP(IPTR); add1(size[fillnum]); END;
		if ildb(rptr)						! filling in region;
		    then begin ifcr false thenc PRINT("<"); endc
			state←1;
			add1(size[fillnum]);
			IBP(IPTR);
			end
		    else begin
			IF ILDB(IPTR) THEN BEGIN
			    dpb(fillnum,rptr);
			    add1(size[fillnum]);
			    end
			  else begin
				border(i,j-1,maskbuf,regbuf,dum,dum,dum,dum,fillnum);
				STATE←0;
				END;
			end;
		if ildb(iptr)						! deletion of small region;
		    then dpb(0,iptr)
		    else state←0;
		end;
	ifcr false thenc PRINT("/"); elsec if (i MOD 10)=0 then PRINT("/"); endc
	end "iloop";
    IF SIZE[TOTARR]>0 THEN PRINT(CRLF,SIZE[TOTARR]," points skipped.",CRLF);
    return(reg);
    end "reginit";

simple internal integer procedure fregion(integer minsiz,bord);
    begin "fregion"
    integer i,j,maxi,maskb,ist,ilim,jst,jlim,iptr,optr;

    maxi←1;
    for i←1 thru reg do
	if size[i]>size[maxi]
	    then maxi←i;
    if size[maxi]<minsiz then return(-1);
    imina[maxi]←(imina[maxi]-bord) MAX 1;
    jmina[maxi]←(jmina[maxi]-bord) MAX 1;
    imaxa[maxi]←(imaxa[maxi]+bord) MIN rows(regbuf);
    jmaxa[maxi]←(jmaxa[maxi]+bord) MIN colms(regbuf);
    getbuf(ilim←imaxa[maxi]-imina[maxi]+1,jlim←jmaxa[maxi]-jmina[maxi]+1,1,maskb←fndbuf);
    putsub(ist←isubst(regbuf)+imina[maxi]-1,jst←jsubst(regbuf)+jmina[maxi]-1,maskb);

    putsup(size[maxi],maskb);
    for i←1 thru ilim do
	begin
	iptr←inptr(imina[maxi]+i-1,jmina[maxi],regbuf);
	optr←outptr(i,1,maskb);
	for j←1 thru jlim do
	    if ildb(iptr)=maxi then idpb(-1,optr) else ibp(optr);
	end;
    size[maxi]←-1;
    return(maskb);
    end "fregion";

simple internal procedure regterm;
    begin
    frebuf(regbuf);
    relary(<(imina,jmina,imaxa,jmaxa,size)>);
    end;

SIMPLE INTERNAL INTEGER PROCEDURE REGCLEAN (INTEGER MINSIZ);
	BEGIN "REGCLEAN"
	INTEGER ROWZ,COLZ,I,J,MASKB,IPTR,OPTR;

	GETBUF(ROWZ←rows(regbuf),COLZ←colms(regbuf),1,MASKB←FNDBUF);
	PUTSUB(ISUBST(REGBUF),JSUBST(REGBUF),maskb);
	FOR I←1 THRU ROWZ DO
		BEGIN
		IPTR←INPTR(I,1,REGBUF);
		OPTR←OUTPTR(I,1,MASKB);
		FOR J←1 THRU COLZ DO
		    IF (DUM←ILDB(IPTR))
			then IF SIZE[DUM]≥MINSIZ
			    then IDPB(-1,OPTR)
			    ELSE IBP(OPTR)
			else ibp(optr);
		END;
	j←0;
	for i←1 thru reg do if size[i]≥minsiz then j←j+size[i];
	putsup(j,maskb);
	RETURN(MASKB);
	END "REGCLEAN";
end "NFREG";